package br.jm.beans;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Locale;

import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.inject.Singleton;

import br.jm.i18n.Holder;
import br.jm.i18n.I18NRepository;

@Named("provider")
@Singleton
public class I18NResourceProvider implements Externalizable {

	private static final long serialVersionUID = 1L;

	transient I18NRepository repo = new I18NRepository(null);

	public Locale getLocale() {
		final FacesContext context = FacesContext.getCurrentInstance();
		final ExternalContext ec = context.getExternalContext();

		Locale loc = ec == null ? null : ec.getRequestLocale();
		loc = loc == null ? Locale.getDefault() : loc;

		return loc;
	}

	public <T> T getMessageContainer(final Class<T> clazz) {
		return repo.getMessageContainer(clazz, getLocale());
	}

	public String localeName() {
		return getLocale().toString();
	}

	@SuppressWarnings("rawtypes")
	@Produces
	// @I18NResource
	public Holder produces(final InjectionPoint ip) {
		final ParameterizedType pt = (ParameterizedType) ip.getType();
		final Type type = pt.getActualTypeArguments()[0];

		final Object instance = repo.getMessageContainer((Class<?>) type, getLocale());

		return new Holder<Object>(instance);
	}

	@Override
	public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
		repo = new I18NRepository(null);
	}

	@Override
	public void writeExternal(final ObjectOutput out) throws IOException {
		// sem estado
	}
}